package com.unitd.base.module.logistics.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.unitd.base.module.logistics.api.TrackQuery;
import com.unitd.base.frame.enums.ResultEnum;
import com.unitd.base.frame.exception.LogisticsException;
import com.unitd.base.frame.plugins.module.service.impl.BaseServiceImpl;
import com.unitd.base.frame.plugins.mybatis.mapper.IBaseDao;
import com.unitd.base.frame.utils.BeanUtils;
import com.unitd.base.frame.utils.DateUtils;
import com.unitd.base.frame.utils.StringUtils;
import com.unitd.base.module.logistics.enums.ExpressStateEnum;
import com.unitd.base.module.logistics.po.ExpressCompany;
import com.unitd.base.module.logistics.po.ExpressData;
import com.unitd.base.module.logistics.po.ExpressDetail;
import com.unitd.base.module.logistics.mybatis.mapper.ExpressCompanyMapper;
import com.unitd.base.module.logistics.mybatis.mapper.ExpressDetailMapper;
import com.unitd.base.module.logistics.service.ExpressDetailService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.MessageFormat;

/**
 * 物流详细信息表信息业务逻辑处理接口实现类
 *
 * @author Hudan
 * @version 1.0
 * @filename ExpressDetailServiceImpl.java
 * @copyright www.unitd.com
 * @date 2019-01-31
 */
@Service
@Slf4j
public class ExpressDetailServiceImpl extends BaseServiceImpl<ExpressDetail, Long> implements ExpressDetailService {

	@Autowired
	private ExpressDetailMapper expressDetailMapper;
	@Autowired
	private ExpressCompanyMapper expressCompanyMapper;
	@Autowired
	private TrackQuery trackQuery;

	/**
	 * @return GenericDao实现类
	 * 定义成抽象方法, 由子类实现, 完成dao的注入
	 */
	@Override
	public IBaseDao<ExpressDetail, Long> getDao() {
		return expressDetailMapper;
	}

	/**
	 * 根据快递公司编号和快递单号获取该快递物流详情
	 *
	 * @param expressCompanyCode 快递公司编号
	 * @param expressNo          快递单号
	 * @return 物流详情
	 */
	@Override
	public ExpressDetail getExpressDetailByData(String expressCompanyCode, String expressNo) {

		// 先根据快递公司名称获取相应的快递公司编号
		ExpressCompany expressCompany = expressCompanyMapper.selectByCode(expressCompanyCode);
		if (BeanUtils.isNull(expressCompany)) {
			String errorMsg = MessageFormat.format(ResultEnum.EXPRESS_COMPANY_NOT_EXIST.getMessage(), expressCompanyCode);
			throw new LogisticsException(ResultEnum.EXPRESS_COMPANY_NOT_EXIST, errorMsg);
		}

		// 根据快递单号和快递公司编号查询是否存在相应的快递信息
		ExpressDetail expressDetail = expressDetailMapper.selectOne(new ExpressDetail(expressCompany.getCode(), expressNo));

		// 当数据库中不存在物流信息的时候,直接调用接口
		if (BeanUtils.isNull(expressDetail) || StringUtils.isNull(expressDetail.getExpressNo())) {
			expressDetail = this.getExpressDetailByInterface(expressCompany.getCode(), expressNo);
		} else {
			// 状态不为已签收,也需要去调用接口
			if (!"3".equalsIgnoreCase(expressDetail.getState())) {
				expressDetail = this.getExpressDetailByInterface(expressCompany.getCode(), expressNo);
			}
		}

		// 只有在查询到物流详情信息的时候,才对具体的轨迹信息做处理
		if (!BeanUtils.isNull(expressDetail)) {

			// 设置快递公司名称
			expressDetail.setExpressCompany(expressCompanyCode);
			// 转换物流状态说明
			expressDetail.setState(ExpressStateEnum.getValueByCode(expressDetail.getState()));

			// 具体物流轨迹信息
			String expressData = expressDetail.getExpressData();
			if (!StringUtils.isNull(expressData)) {
				expressDetail.setExpressData(null);
				expressDetail.setExpressDataArray(JSON.parseArray(expressData, ExpressData.class));
			}
		}
		return expressDetail;
	}

	/**
	 * 通过接口获取实时物流信息,并保存入库或更新
	 *
	 * @param expressCompany 快递公司编号
	 * @param expressNo      快递单号
	 * @return 物流详情
	 */
	private ExpressDetail getExpressDetailByInterface(String expressCompany, String expressNo) {
		ExpressDetail expressDetail = null;

		// 调用接口,获取即时物流信息
		String result = trackQuery.getTrackQueryByExpCodeAndNo(expressCompany, expressNo);
		if (!StringUtils.isNull(result)) {
			JSONObject jsonObject = JSON.parseObject(result);

			// 将本次查询得到的物流详情信息保存入库
			expressDetail = new ExpressDetail();
			// 快递单号
			expressDetail.setExpressNo(BeanUtils.toStr(jsonObject.get("LogisticCode")));
			// 快递公司编号, 与EXPRESS_COMPANY表中的code对应起来
			expressDetail.setExpressCompany(BeanUtils.toStr(jsonObject.get("ShipperCode")));
			// 物流轨迹详情信息
			expressDetail.setExpressData(BeanUtils.toStr(jsonObject.get("Traces")));
			// 物流状态(-1未查到快递信息、0在途中、1已揽收、2疑难、3已签收、4退签、5同城派送中、6退回、7转单)
			expressDetail.setState(BeanUtils.toStr(jsonObject.get("State")));
			expressDetail.setUpdateTime(DateUtils.getCurrTime("yyyymmddHHMMSS"));
		}

		if (!BeanUtils.isNull(expressDetail)) {
			// 说明原来存在,只是现在通过接口获取之后,需要重新更新数据库
			if (!BeanUtils.isNull(expressDetail.getId())) {
				expressDetailMapper.updateByPrimaryKeySelective(expressDetail);
			} else {
				expressDetail.setCreateTime(DateUtils.getCurrTime("yyyymmddHHMMSS"));
				expressDetailMapper.insertSelective(expressDetail);
			}
		}
		return expressDetail;
	}
}